/*
 * @Author: xiaosihan 
 * @Date: 2023-02-06 15:22:57 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2024-03-10 11:27:28
 */
import { autorun } from "mobx";
import { AmbientLight, DirectionalLight, Box3, Object3D, PerspectiveCamera, Mesh, PointLight, Vector3, DoubleSide, BoxGeometry, MeshStandardMaterial } from "three";
import ThreeBase from "three-base";
import threeUtils from "three-base/threeUtils";
import Building from "./component3d/Building/Building";

import Lensflare from "./component3d/Lensflare/Lensflare";
import MeshBase from "./component3d/MeshBase/MeshBase";
import Sky from "./component3d/Sky/Sky";
import publicMaterial from "./component3d/WindowGroup/publicMaterial";
import homeStore from "./homeStore";
import keyContorls from "three-base/keyContorls";
import { max, round } from "lodash";
// import { SUBTRACTION, INTERSECTION, ADDITION, Brush, Evaluator } from 'three-bvh-csg';
import BuildGroup from "./component3d/BuildGroup/BuildGroup";
import Ground from "./component3d/Ground/Ground";

/**
 *
 *
 * @class HomeRender
 * @extends {ThreeBase}
 */
class HomeRender extends ThreeBase {

    constructor() {
        super();
    }

    // 环境光
    ambientLight = (() => {
        const ambientLight = new AmbientLight("#fff", 2.0);
        this.scene.add(ambientLight);
        return ambientLight;
    })();

    //点光源
    pointLight = (() => {
        const pointLight = new PointLight("#fff", 2.0);
        pointLight.distance = 100;
        pointLight.decay = 0;
        pointLight.position.set(50, 40, 50);
        this.scene.add(pointLight);
        return pointLight;
    })();

    // 方向光
    directionalLight = (() => {
        const directionalLight = new DirectionalLight("#fff", 2.0);
        directionalLight.position.set(-10, 10, 5);
        directionalLight.target.position.set(0, 0, 0);
        directionalLight.castShadow = true;
        directionalLight.shadow.mapSize.set(1024, 1024);
        this.scene.add(directionalLight);
        return directionalLight;
    })();

    init() {
        super.init();
        this.gridHelper.visible = false;
        this.controls.maxPolarAngle = Math.PI / 2;
        // this.controls.screenSpacePanning = false;
        // this.controls.panSpeed = 0;
        // this.resetLookAt({
        //     center: new Vector3(1.3, 2.903, -4.3),
        //     position: new Vector3(8.321, 5.403, -8.802),
        // });

        // 开发模式时还原记录的位置
        if (threeUtils.isDev && localStorage.dispaly_window_lookAt) {
            this.resetLookAt({
                ...JSON.parse(localStorage.dispaly_window_lookAt)
            });
        }

        // 开发模式时记录当前的位置
        if (threeUtils.isDev) {
            this.controls.addEventListener("change", () => {
                localStorage.dispaly_window_lookAt = JSON.stringify(this.getLookAt());
            })
        }

        if (threeUtils.isProd || (threeUtils.isDev && !localStorage.dispaly_window_lookAt)) {
            this.resetLookAt({
                center: new Vector3(1.5, -0.667, -4.735),
                position: new Vector3(1.5, 2, -4.735).add(new Vector3(10, 1, 0))
            });
        }

    }

    //天空
    sky = (() => {
        const sky = new Sky();
        this.scene.add(sky);
        return sky;
    })();

    // 光晕
    // Lensflare = (() => {
    //     const lensflare = new Lensflare();
    //     lensflare.position.set(-10, 5, 10);
    //     this.scene.add(lensflare);
    //     return lensflare;
    // })();

    // 装饰地面
    ground1 = (() => {
        const ground1 = new Ground();
        ground1.position.set(0, -0.16, 0);
        ground1.scale.set(200, 1, 200);
        this.scene.add(ground1);
        return ground1;
    })();

    // 查看对象
    lookatObjects({
        objects,
        duration = 1000,
        direction = new Vector3(0.3, 0.3, 1),
        offset = new Vector3(0, 0, 0),
        distance = 1
    }: {
        objects: Array<Object3D>,
        duration?: number,
        direction?: Vector3,
        offset?: Vector3,
        distance?: number
    }) {
        const box3 = new Box3();
        objects.map(o => box3.expandByObject(o));
        const size = new Vector3();
        box3.getSize(size);
        const center = new Vector3();
        box3.getCenter(center);

        center.add(offset);
        const modelSize = size.length() * distance;
        const camera = this.getCamera();
        const { fov } = camera as PerspectiveCamera;
        const cameraDistance = modelSize / (2 * Math.tan(fov * Math.PI / 360));
        const position = direction.setLength(cameraDistance).add(center);
        this.setLookAt({ center, position, duration });
    }

    // 楼房组对象
    BuildGroup = (() => {
        const buildGroup = new BuildGroup();

        buildGroup.addEventListener("loaded", () => {
            if (this.BuildGroup.children[0]) {
                this.lookatObjects({
                    objects: [this.BuildGroup.children[0].topFloor, this.BuildGroup.children[0].oneFloor],
                    direction: new Vector3(1, 0, 0),
                });
            }
        });

        this.scene.add(buildGroup);
        return buildGroup;
    })();

    // 监听数据的改变
    // dispose1 = autorun(async () => {
    //     const { buildDatas, floorHeight } = homeStore;
    //     if (floorHeight) {
    //         await this.build1.setData(buildDatas[0]);
    //         await this.build2.setData(buildDatas[1]);
    //         await this.build3.setData(buildDatas[2]);
    //     }
    // });



    render(): void {

        const camera = homeRenderer.getCamera();

        // 相机朝向不能到地下去
        const targetY = homeRenderer.controls.target.y;
        homeRenderer.controls.target.y = Math.max(targetY, 0);
        camera.position.y -= Math.min(targetY, 0);

        this.pointLight.position.copy(camera.position);
        super.render();
    }


}


const homeRenderer = window.homeRenderer = new HomeRender();

export default homeRenderer;